﻿import flash.geom.Matrix;
import flash.geom.Point;
dynamic class MyTesture.SimpleTestures extends MovieClip {
	private static var testurecount:Number = 0;
	/**
	 * 获取一个新的贴图数量位置
	 */
	public static function get NewTestIndex():Number {
		return testurecount++;
	}
	/**
	 * 所有贴图数量
	 */
	public static function get TestureCount():Number {
		return testurecount;
	}
	
	
	
	private var $rootmc:MovieClip;
	private var $mc1:MovieClip;
	private var $picmc:MovieClip;
	private var $mask:MovieClip;
	private var $pic:pictureBox;
	private var $piclink:String;
	private var $picurl:String;
	private var $points:Array;
	private var $defColor:Number = 0x666666;
	private var $UV:Point;
	
	private var _say:Say;
	private var $drawSingleSide:Boolean = true;
	
	private var $testureType:String = "p";
	
	/**
	 * UV方向的缩放
	 */
	public function get UVScale():Point {
		return new Point(this.$pic.Width, this.$pic.Height);
	}
	public function set UVScale(value:Point) {
		this.$pic.Width = value.x;
		this.$pic.Height = value.y;
	}
	/**
	 * 只绘制顺时针方向面
	 */
	public function get DrawSingleSide():Boolean {
		return this.$drawSingleSide;
	}
	/**
	 * 只绘制顺时针方向面
	 */
	public function set DrawSingleSide(value:Boolean) {
		this.$drawSingleSide = value;
		this.checkTestureVisible();
	}
	/**
	 * 创建贴图的mc
	 */
	public function get TestureMc():MovieClip {
		return this.$rootmc;
	}
	
	/**
	 * 贴图外部图片或swf文件位置
	 */
	public function get PicUrl():String { 
		return $picurl; 
	}
	/**
	 * 贴图外部图片或swf文件位置
	 */
	public function set PicUrl(value:String):Void {
		$picurl = value;
		this.$picmc.clear();
		this.$pic.PicUrl = value;
		this.$pic.load();
	}
	/**
	 * 贴图内部link
	 */
	public function get PicLink():String { 
		return $piclink; 
	}
	
	/**
	 * 贴图内部link
	 */
	public function set PicLink(value:String):Void {
		$piclink = value;
		this.$picmc.clear();
		this.$pic.PicLink = this.$piclink;
		this.$pic.load();
	}
	/**
	 * 贴图点（按不同方式分布点位置）
	 * 贴图方式
	 * p:   b--c        d:      a
	 *      | /               / |
	 *      a                c--b
	 */
	public function get Points():Array { 
		return $points; 
	}
	/**
	 * 贴图点（按不同方式分布点位置）
	 * 贴图方式
	 * p:   b--c        d:      a
	 *      | /               / |
	 *      a                c--b
	 */
	public function set Points(value:Array):Void {
		if (value.length >= 3) {
			for (var i:Number = 0; i < value.length; i++) {
				if (value[i].testure == undefined) {
					value[i].testure = new Object();
				}
				value[i].testure[this.ID] = this;
			}
			$points = value;
			this.testure();
		}else {
			_say.esay("Points shoud be 3");
		}
	}
	/** 贴图方式
	 * p:   b--c        d:      a
	 *      | /               / |
	 *      a                c--b
	 */
	public function get TestureType():String { 
		return $testureType; 
	}
	/**
	 * 贴图方式
	 * p:   b--c        d:      a
	 *      | /               / |
	 *      a                c--b
	 * 
	 */
	public function set TestureType(value:String):Void {
		if (value == "p" || value=="d") {
			$testureType = value;
			this.setTestureType();
		}
	}
	/**
	 * 贴图UV位置 (x=0-100,y=0-100);
	 */
	public function get UV():Point { 
		return $UV; 
	}
	/**
	 * 贴图UV位置 (x=0-100,y=0-100);
	 */
	public function set UV(value:Point):Void {
		$UV = value;
		this.setUV();
	}
	/**
	 * 该贴图唯一标识
	 */
	public function get ID():String {
		return this._say.Name;
	}
	
	/**
	 * 基本贴图类（三角形）
	 * @param	root 贴图位置
	 */
	public function SimpleTestures(root:MovieClip) {
		if (root == undefined) {
			root = this;
		}
		this.initsay();
		this.$rootmc = root;
		this.initvars();
		this.initmcs();
		_say.msay("inited!");
	}
	
	private function initvars() {
		this.$UV = new Point(0, 0);
		this.$points = new Array();
		this.$points.push(new Point(50,100));
		this.$points.push(new Point(0,0));
		this.$points.push(new Point(100,10));
	}
	private function initmcs():Void{
		this.$mc1 = this.$rootmc.createEmptyMovieClip(this.ID, this.$rootmc.getNextHighestDepth());
		this.$mask = this.$mc1.createEmptyMovieClip("mask", 10);
		this.$picmc = this.$mc1.createEmptyMovieClip("picmc", 5);
		this.$pic = new pictureBox(this.$picmc);
		this.$pic.Width = 100;
		this.$pic.Height = 100;
		this.$pic.Scal = "both";
		this.drowTriangle(this.$picmc, 100, 100, this.$defColor);
		this.setTestureType();
		
		this.drowTriangle(this.$mask, 100.1, 100.1, this.$defColor);
		this.$picmc.setMask(this.$mask);
	}
	private function checkTestureVisible() {
		
		if (this.$drawSingleSide) {
			if (getPointDirection()) {
				this.$picmc._visible = true;
			}else {
				this.$picmc._visible = false;
			}
		}else {
			this.$picmc._visible = true;
		}
	}
	private function getPointDirection(xx0, yy0, xx1, yy1, xx2, yy2):Boolean {
		if (xx0 == undefined) {
			xx0 = this.$points[0].x;
		}
		if (yy0 == undefined) {
			yy0 = this.$points[0].y;
		}
		if (xx1 == undefined) {
			xx1 = this.$points[1].x;
		}
		if (yy1 == undefined) {
			yy1 = this.$points[1].y;
		}
		if (xx2 == undefined) {
			xx2 = this.$points[2].x;
		}
		if (yy2 == undefined) {
			yy2 = this.$points[2].y;
		}
		var fun:Function = Math2.lineEquation( { x0:xx0, y0:yy0, x1:xx2, y1:yy2 }, false);
		var my:Number = fun(xx1);
		if (yy1 > my) {
			if(xx2>xx0){
				//逆时针
				return false;
			}else {
				//顺时针
				return true;
			}
		}else {
			if(xx2<xx0){
				//逆时针
				return false;
			}else {
				//顺时针
				return true;
			}
		}
	}
	/**
	 * 设置贴图方式
	 */
	private function setTestureType() {
		if(this.$testureType=="d"){
			this.$picmc._rotation = 180;
		}
		this.setUV();
	}
	/**
	 * 改变UV贴图位置
	 */
	private function setUV() {
		if(this.$testureType=="p"){
			this.$picmc._x = -UV.x;
			this.$picmc._y = -UV.y;
		}else {
			this.$picmc._x = UV.x;
			this.$picmc._y = UV.y;
		}
	}
	/**
	 * 绘制三角形
	 * @param	mc 绘制位置
	 * @param	w 宽度
	 * @param	h 高度
	 * @param	color 颜色
	 */
	private function drowTriangle(mc:MovieClip, w:Number, h:Number, color:Number) {
		mc.clear();
		mc.beginFill(color, 100);
		mc.moveTo(0, 0);
		mc.lineTo(w, 0);
		mc.lineTo(0, h);
		mc.lineTo(0, 0);
		mc.endFill();
	}
	/**
	 * 贴图
	 * (b)--(c)
	 *  |  /
	 * (a)
	 * @param	innoMove (true)贴图元移动，对齐点b;
	 *                   (false)贴图根移动，对齐点b;
	 * 
	 * 
	 */
	public function testure(innoMove:Boolean) {
		if (this.$drawSingleSide) {
			if(!getPointDirection()){
				this.$picmc._visible = false;
				return;
			}else {
				this.$picmc._visible = true;
			}
		}else {
			this.$picmc._visible = true;
		}
		var w = ($points[2]).x - ($points[1]).x;
		var h = ($points[0]).y - ($points[1]).y;
		var hl = (($points[2]).y - ($points[1]).y) / 100;
		var wl = (($points[0]).x - ($points[1]).x) / 100;
		var m1:Matrix = new Matrix();
		m1.scale(w/100,h/100);
		m1.b = hl;
		m1.c = wl;
		this.$mc1.transform.matrix = m1;
		
		if (innoMove) {
			this.$rootmc._x = 0;
			this.$rootmc._y = 0;
			this.$mc1._x = ($points[1]).x;
			this.$mc1._y = ($points[1]).y;
		}else {
			this.$mc1._x = 0;
			this.$mc1._y = 0;
			this.$rootmc._x = ($points[1]).x;
			this.$rootmc._y = ($points[1]).y;
		}
		
		//trace(this.$points);
		
	}
	/**
	 * get angle of two points with X axes
	 * @param	x1 x of point1
	 * @param	y1 y of point1
	 * @param	x2 x of point2
	 * @param	y2 y of point2
	 * @return the angle of two points with X axes
	 */
	private function getAlpha(x1, y1, x2, y2):Number {
		var yl:Number = y2 - y1;
		var xl:Number = x2 - x1;
		return Math.atan2(yl, xl);
	}
	/**
	 * get distence of two points
	 * @param	x1 x of point1
	 * @param	y1 y of point1
	 * @param	x2 x of point2
	 * @param	y2 y of point2
	 * @return	the distence of two points
	 */
	private function dis(x1, y1, x2, y2):Number {
		return Math.pow((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2), 0.5);
	}
	
	
	public function toString() {
		if (arguments[0] == "point") {
			return this.ID+" "+this.Points[0].toString()+","+this.Points[1].toString()+","+this.Points[2].toString()
		}
		
		
		
		else {
			return this.ID;
		}
	}
	
	private function initsay():Void{
		this._say = new Say("ST" + SimpleTestures.NewTestIndex);
		this._say.addListener(this);
		this[Say.M_SAY] = this.sayfun;
	}
	private function sayfun(o) {
		if (this.say == undefined) {
			trace(o);
		}else {
			this.say(o);
		}
	}
	
}